home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 46
/
Amiga Format CD46 (1999-10-20)(Future Publishing)(GB)[!][issue 1999-12].iso
/
-in_the_mag-
/
banging_the_metal
/
draw_logic
/
draw_logic.text
< prev
next >
Wrap
Text File
|
1999-09-10
|
6KB
|
152 lines
BRUTE-FORCE VECTOR GRAPHICS in BASIC and ASSEMBLY code
This is an extract from the DIY Toolkit (Qdos cardware) package. It is of interest because it
includes BASIC and 68K assembler code to draw lines, a job which the Amiga can do in
hardware. The complete DIY Toolkit package is available from Qdos pages like this one:
http://www.users.imaginet.fr/~godefroy/english/QDOS.html
The DRAW routines come in two forms. The file DRAW_ASM is the assembly code, tested
using HiSoft's DevPac and Metacomco's assembler. You may edit and re-assemble this with
your own assembler. DRAW_DEMO_BAS is a cut-down version in BASIC, limited to certain
angles (see the discussion of Quadrants in the magazine) but thus even more similar to the
Amiga hardware implementation.
The Algorithm
The algorithm to generate a straight line is simple in principle, but complicated by the need to
draw lines in any direction at any angle. The machine code is convoluted and uses all sixteen
68008 registers, so I wrote the algorithm in SuperBASIC for test purposes, after I wrote PLOT
and before I machine-coded DRAW.
×DRAW_DEMO_BAS shows the algorithm in block-structured BASIC. The first stage is to find
the direction and magnitude of the line, in the X and Y dimensions. DX indicates whether the
line moves left (-1), right (+1) or neither left or right (0). DY is the same for vertical movement -
in other words, DX and DY indicate the approximate direction of the line, relative to the
horizontal and vertical.
MX and MY indicate the number of pixels to be moved vertically or horizontally. The values
are always positive, or zero, thanks to the ABS function. Assuming pixels are square, you can
draw a straight line at any angle between 0 and 45 degrees by stepping through a series of
points equal to the greater of MX and MY.
At each step you advance X or Y (whichever is greater) by one. Whether you advance the
other co-ordinate depends on the slope of the line. Since we want a straight line, the need for
an alternate step depends on how long it was since you last took one.
If MX equals MY the angle is 45 degrees and you step one pixel horizontally and vertically at
each stage. If either DX or DY is zero, the angle is zero and you just step either horizontally or
vertically until you get to the end. Most lines fall between these two angles. Sometimes you
can make the step in DX and DY, but sometimes you must just step in the main direction,
indicated by the greater of MX and MY.
The program creates two step values for each dimension; DX and DY, plus DDX and DDY for
the alternative steps needed to cope with intermediate angles. DDX and DDY hold the 'main'
direction. If MX exceeds MY, DDX is the same as DX, and DDY is zero. If MY is greater than
MX, DDY matches DY and DDX is zero.
The problem is deciding when to step by (DX,DY), and when to use (DDX,DDY). The correct
mix is determined by the ratio of MX and MY. If MX is relatively small, you must take many
vertical steps for every horizontal one.
Since we want a continuous line, the total number of STEPS, and points to plotted, is given by
the greater of X and Y. The number of jumps out of line, or non-contiguous PARTS, is clearly
the lesser of X and Y.
For each step the algorithm adds the number of PARTS to a temporary variable. If the result
exceeds the total in STEPS, the algorithm uses DX and DY to find the next point; otherwise it
uses DDX and DDY. At the start, TEMP is set to half of the number of steps, so jumps out of
line are evenly spaced.
Any algorithm that works for angles between 0 and 45 degrees can be persuaded to cover a
full circle by swapping X and Y and allowing positive and negative steps. This is the role of the
SIGN function-calls and the first IF test. The Amiga Blitter must be programmed with three bits
to indicate the quadrant.
The Assembly code
PLOT sets a single dot in any window on the QL screen. It takes two or three integer
parameters - an optional channel number, followed by the X and Y co-ordinates of the dot you
want to set.
DRAW takes the same parameters - an optional channel, then the X and Y co-ordinates of the
end of a line. It draws a straight line joining the last position used with PLOT to the dot at the
co-ordinate supplied with DRAW. For instance this command draws a red and green striped
line from the top left corner of the screen to the bottom right:
WINDOW 512,256,0,0 : INK 4,2 : PLOT 0,0 : DRAW 511,255
PLOT and DRAW work in any CONsole or SCReen window; they use the current INK colour
and recognise OVER -1 as well as OVER 0 or 1. OVER -1 combines the line colour and the
background in such a way that re-drawing a line in the same colour restores the original
background.
PLOT and DRAW use the 'pixel co-ordinate' scheme, explained in the 'Concepts' section of
the QL User Guide. Co-ordinates are relative to the top left corner of the specified window, as
for BLOCK and PIXEL%.
PLOT and DRAW check their parameters to ensure that they fit in the specified or default
window. The default channel number is #1 so you can re-direct both commands to other
channels with USE, the March 1988 DIY Toolkit offering.\par
The commands report 'channel not open' if the channel is closed. You get a 'bad parameter'
error if you specify the wrong type of channel or the wrong number of parameters. 'Error in
expression' indicates that one or more parameters could not be evaluated as integers.\par
PLOT and DRAW return 'not complete' if called when CTRL-F5 has been pressed, to pause
the display. You don't see this message under normal circumstances, as the operating system
traps it, temporarily suspends the calling task, and re-tries until a key is pressed, re-enabling
display output.
For more details and much more interesting code and commentary, see Volume G of DIY
Toolkit, and please send me an email (simon@studio.co.uk) or a postcard if you use it!